#!/bin/bash -x

kata_coco_top_dir="$HOME/workspace/CoCo"

if [ ! -e ${kata_coco_top_dir} ]; then
  mkdir -p ${kata_coco_top_dir}
fi

source $HOME/.bashrc

install_basic_deps () {
  echo "[Install basic dependencies]"

  if [ ! -e /etc/yum.repos.d/AnolisOS-DDE.repo ]; then
    sudo tee /etc/yum.repos.d/AnolisOS-DDE.repo <<EOF
[DDE]
name=AnolisOS-\$releasever - DDE
baseurl=http://mirrors.openanolis.cn/anolis/\$releasever/DDE/\$basearch/os
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ANOLIS
gpgcheck=1
EOF
  fi

  if [ ! -e /etc/yum.repos.d/AnolisOS-Devel.repo ]; then
    sudo tee /etc/yum.repos.d/AnolisOS-Devel.repo <<EOF
[Devel]
name=AnolisOS-\$releasever - Devel
baseurl=http://mirrors.openanolis.cn/anolis/\$releasever/Devel/\$basearch/os
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ANOLIS
gpgcheck=1
EOF
  fi

  if [ ! -e /etc/yum.repos.d/AnolisOS-Nightly.repo ]; then
    sudo tee /etc/yum.repos.d/AnolisOS-Nightly.repo <<EOF
[Nightly]
name=AnolisOS-\$releasever - Nightly
baseurl=http://mirrors.openanolis.cn/anolis/\$releasever/Nightly/os/\$basearch/os
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ANOLIS
gpgcheck=0
EOF
  fi

  sudo yum makecache

  sudo yum install -y curl wget git tar
  sudo yum install -y yum-utils \
    device-mapper-persistent-data lvm2
}

install_basic_deps

# Install go
install_go_lang () {
  go_version="1.22.2"
  echo "[Install go (${go_version})]"
  command go version > /dev/null
  if [ $? -ne 0 ]; then
    if [ ! -e "/tmp/go${go_version}.linux-amd64.tar.gz" ]; then
      wget -O /tmp/go${go_version}.linux-amd64.tar.gz \
        https://golang.org/dl/go${go_version}.linux-amd64.tar.gz
    fi
    sudo tar -C /usr/local -xzf /tmp/go${go_version}.linux-amd64.tar.gz
    sed -i '$aexport PATH=$PATH:/usr/local/go/bin' ~/.bashrc
  fi
}

install_go_lang

# Install rust
install_rustc () {
  rustc_version="1.75.0"
  echo "[Install rust (${rustc_version})]"
  command rustc --version > /dev/null
  if [ $? -ne 0 ]; then
    mkdir $HOME/.cargo/ || true
    cat > $HOME/.cargo/config.toml <<EOF
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"

# 替换成你偏好的镜像源
replace-with = 'tuna'

# 清华大学
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

# 中国科学技术大学
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"

# 上海交通大学
[source.sjtu]
registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index"

# rustcc社区
[source.rustcc]
registry = "git://crates.rustcc.cn/crates.io-index"
EOF

    export RUSTUP_DIST_SERVER="https://rsproxy.cn"
    export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup"

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
      sh -s -- -y --default-toolchain=${rustc_version} && \
      source $HOME/.cargo/env && \
      rustc --version
  fi
}

install_rustc

install_docker () {
  echo "[Install docker & containerd]"
  # Remove docker & containerd installed from yum repos, we'll install official
  # release
  sudo yum remove -y docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine

  # Download and install docker's official release, this release contains
  # containerd
  sudo mkdir -p /usr/local/bin
  if [ ! -e ${kata_coco_top_dir}/docker-28.0.2.tgz ]; then
    wget -O ${kata_coco_top_dir}/docker-28.0.2.tgz \
      https://download.docker.com/linux/static/stable/x86_64/docker-28.0.2.tgz
  fi
  sudo tar -zxvf ${kata_coco_top_dir}/docker-28.0.2.tgz \
    -C /usr/local/bin --strip-components=1

  sudo mkdir -p /usr/local/lib/systemd/system/
  sudo tee /usr/local/lib/systemd/system/containerd.service <<EOF
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target dbus.service

[Service]
#uncomment to enable the experimental sbservice (sandboxed) version of containerd/cri integration
#Environment="ENABLE_CRI_SANDBOXES=sandboxed"
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target
EOF
  sudo tee /usr/local/lib/systemd/system/docker.socket <<EOF
[Unit]
Description=Docker Socket for the API

[Socket]
# If /var/run is not implemented as a symlink to /run, you may need to
# specify ListenStream=/var/run/docker.sock instead.
ListenStream=/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target
EOF
  sudo tee /usr/local/lib/systemd/system/docker.service <<EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target nss-lookup.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/local/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP \$MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target
EOF

  sudo groupadd docker || true
  sudo usermod -aG docker $USER
  sudo systemctl daemon-reload && \
  sudo systemctl enable containerd && \
  sudo systemctl enable docker
  sudo systemctl restart containerd && \
  sudo systemctl restart docker

  # Install docker buildx
  docker_buildx_url="https://github.com/docker/buildx/releases/download/v0.20.0/buildx-v0.20.0.linux-amd64"
  docker_buildx_cache="${kata_coco_top_dir}/buildx-v0.20.0.linux-amd64"
  docker_buildx_path="/usr/local/lib/docker/cli-plugins/docker-buildx"
  if [ ! -e ${docker_buildx_cache} ]; then
    curl -SL ${docker_buildx_url} -o ${docker_buildx_cache}
  fi
  if [ ! -e ${docker_buildx_path} ]; then
    sudo mkdir -p $(dirname ${docker_buildx_path}) || true
    sudo cp ${docker_buildx_cache} ${docker_buildx_path}
    sudo chmod +x ${docker_buildx_path}
  fi

  docker buildx version
  sudo docker buildx version

  # Setup registry mirrors for docker & containerd
  registry_mirror_list="\"https:\/\/docker.m.daocloud.io\",\"https:\/\/noohub.ru\",\"https:\/\/huecker.io\",\"https:\/\/dockerhub.timeweb.cloud\",\"https:\/\/registry.cn-hangzhou.aliyuncs.com\",\"https:\/\/mirror.ccs.tencentyun.com\",\"https:\/\/docker.mirrors.ustc.edu.cn\",\"https:\/\/hub-mirror.c.163.com\""

  if [ -e /etc/docker/daemon.json ] && [ $(wc -l /etc/docker/daemon.json | awk '{print $1}') -gt 2 ]; then
    if [ $(grep -c "\"registry-mirrors\":" /etc/docker/daemon.json) -eq 0 ]; then
      sudo sed -i "1a\  \"registry-mirrors\": [${registry_mirror_list}]," \
        /etc/docker/daemon.json
    fi
  else
    sudo mkdir -p /etc/docker || true
    cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "registry-mirrors": [$(echo ${registry_mirror_list} | sed "s!\\\/!\/!g")]
}
EOF
  fi
  sudo mkdir -p /etc/containerd/
  sudo containerd config default | sudo tee /etc/containerd/config.toml
  containerd_registry_mirror_marker="\[plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors\]"
  containerd_registry_mirror_docker_marker="\[plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"\]"
  containerd_registry_mirror_gcr_marker="\[plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"k8s.gcr.io\"\]"
  if [ $(sudo grep -c "${containerd_registry_mirror_marker}" /etc/containerd/config.toml) -ne 0 ]; then
    if [ $(sudo grep -c "${containerd_registry_mirror_docker_marker}" /etc/containerd/config.toml) -eq 0 ]; then
      sudo sed -i "/${containerd_registry_mirror_marker}/a\\
        ${containerd_registry_mirror_docker_marker}\n\
          endpoint = \[${registry_mirror_list}\]" \
        /etc/containerd/config.toml
    fi
    if [ $(sudo grep -c "${containerd_registry_mirror_gcr_marker}" /etc/containerd/config.toml) -eq 0 ]; then
      sudo sed -i "/${containerd_registry_mirror_marker}/a\\
        ${containerd_registry_mirror_gcr_marker}\n\
          endpoint = \[\"https:\/\/registry.aliyuncs.com\/google_containers\"\]" \
        /etc/containerd/config.toml
    fi
  fi

  # Setup network proxy
  docker_proxy_dir="/etc/systemd/system/docker.service.d"
  containerd_proxy_dir="/etc/systemd/system/containerd.service.d"
  sudo mkdir -p ${docker_proxy_dir} || true
  sudo mkdir -p ${containerd_proxy_dir} || true
  cat <<EOF | sudo tee ${docker_proxy_dir}/proxy.conf
[Service]
EOF
  cat <<EOF | sudo tee ${containerd_proxy_dir}/proxy.conf
[Service]
EOF
  if [ "X$HTTPS_PROXY" != "X" ]; then
    cat <<EOF | sudo tee -a ${docker_proxy_dir}/proxy.conf
Environment="HTTPS_PROXY=${HTTPS_PROXY}"
EOF
    cat <<EOF | sudo tee -a ${containerd_proxy_dir}/proxy.conf
Environment="HTTPS_PROXY=${HTTPS_PROXY}"
EOF
  elif [ "X$https_proxy" != "X" ]; then
    cat <<EOF | sudo tee -a ${docker_proxy_dir}/proxy.conf
Environment="HTTPS_PROXY=${https_proxy}"
EOF
    cat <<EOF | sudo tee -a ${containerd_proxy_dir}/proxy.conf
Environment="HTTPS_PROXY=${https_proxy}"
EOF
  fi
  if [ "X$HTTP_PROXY" != "X" ]; then
    cat <<EOF | sudo tee -a ${docker_proxy_dir}/proxy.conf
Environment="HTTP_PROXY=${HTTP_PROXY}"
EOF
    cat <<EOF | sudo tee -a ${containerd_proxy_dir}/proxy.conf
Environment="HTTP_PROXY=${HTTP_PROXY}"
EOF
  elif [ "X$http_proxy" != "X" ]; then
    cat <<EOF | sudo tee -a ${docker_proxy_dir}/proxy.conf
Environment="HTTP_PROXY=${http_proxy}"
EOF
    cat <<EOF | sudo tee -a ${containerd_proxy_dir}/proxy.conf
Environment="HTTP_PROXY=${http_proxy}"
EOF
  fi
  if [ "X$NO_PROXY" != "X" ]; then
    cat <<EOF | sudo tee -a ${docker_proxy_dir}/proxy.conf
Environment="NO_PROXY=${NO_PROXY}"
EOF
    cat <<EOF | sudo tee -a ${containerd_proxy_dir}/proxy.conf
Environment="NO_PROXY=${NO_PROXY}"
EOF
  elif [ "X$no_proxy" != "X" ]; then
    cat <<EOF | sudo tee -a ${docker_proxy_dir}/proxy.conf
Environment="NO_PROXY=${no_proxy}"
EOF
    cat <<EOF | sudo tee -a ${containerd_proxy_dir}/proxy.conf
Environment="NO_PROXY=${no_proxy}"
EOF
  fi

  sudo systemctl daemon-reload && \
  sudo systemctl restart containerd && \
  sudo systemctl restart docker
}

install_docker
